# -*- coding: utf-8 -*-
import logging
import random
import time
from traceback import format_exc
from scrapy.utils.project import get_project_settings
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from zc_core.dao.cookie_dao import CookieDao
from zc_core.middlewares.proxies.cached_pool import CachedProxyPool
from zc_core.util.instance_builder import build_instance

logger = logging.getLogger('login')


class SeleniumLogin(object):
    # 登录地址
    login_url = 'https://egologin.ctg.com.cn/cas/login?sysid=ipu_sanxia&service=https%3A%2F%2Fego.ctg.com.cn%2Fyuncai%2FSSO%2Flogin.jsp%3Fu64%3Dfalse%26r%3D%2Fyuncai%2FSSO%2Floginpageandredirect.html&registertype=72941b226fa7bff1fcac9ec5ccba2d05038cd881'
    index_url = 'https://ego.ctg.com.cn/mall-cli-portal/static/pages/index/index.html#/index/index'
    cookie_white_list = ['ucuserid', 'tenantid', 'token', 'u_usercode', 'u_logints']

    def __init__(self, timeout=60):
        settings = get_project_settings()
        self.max_login_retry = settings.get('MAX_LOGIN_RETRY', 2)
        self.timeout = timeout
        self.option = webdriver.ChromeOptions()

        # 构建校验器对象
        proxy_pool_class = settings.get('PROXY_POOL_CLASS', '')
        if proxy_pool_class:
            self.pool = build_instance(proxy_pool_class, settings)
        else:
            self.pool = CachedProxyPool(settings)
        self.option.add_argument('--proxy-server=http://%s' % self.pool.get_proxy())
        # self.option.add_argument('--headless')
        self.option.add_argument('--no-sandbox')
        self.accounts = settings.get('ACCOUNTS', [])

    def new_chrome(self):
        self.browser = webdriver.Chrome(chrome_options=self.option)
        self.browser.set_window_size(1400, 700)
        self.browser.set_page_load_timeout(self.timeout)

    def login(self):
        # try:
        self.new_chrome()
        self.browser.get(self.login_url)

        account = random.choice(self.accounts)
        logger.info('login account: %s' % account)

        username = self.browser.find_element_by_id("username")
        username.clear()
        username.send_keys(list(account.keys())[0])
        time.sleep(1)

        password = self.browser.find_element_by_id("password")
        password.clear()
        password.send_keys(list(account.values())[0])
        time.sleep(1)

        # 登录
        submit = self.browser.find_element_by_id("submit_btn_login")
        submit.click()
        time.sleep(5)

        # 尝试主动加载首页
        self.browser.get(self.index_url)
        time.sleep(3)

        # 校验
        WebDriverWait(self.browser, 8).until(EC.title_contains('三峡e购'))
        cookies = self.browser.get_cookies()
        logger.info('--> cookies: %s' % cookies)

        self.browser.close()
        return cookies
        # except Exception as e:
        #     _ = e
        #     logger.error(format_exc())
        #     self.browser.close()
        #     return list()

    # cookie获取
    def get_cookies(self):
        cookie_dao = CookieDao()
        cookies = cookie_dao.get_cookie()
        if not cookies:
            cookies = self.__get_cookies(0)
            cookie_dao.save_cookie(cookies, expire_time=7200)
        return cookies

    # 最大重试登录获取cookie
    def __get_cookies(self, retry):
        # 登录获取
        arr = self.login()
        if not arr:
            # 失败重试
            if retry <= self.max_login_retry:
                retry = retry + 1
                logger.info('--> 登录失败重试: %s次' % retry)
                return self.__get_cookies(retry)
            else:
                logger.info('--> 放弃失败重试: %s次' % retry)
                return dict()

        # 重组
        cookies = dict()
        for cookie in arr:
            cookie_key = cookie.get('name')
            if cookie_key in self.cookie_white_list:
                cookies[cookie_key] = cookie.get('value')

        # 校验
        if not cookies or not self._validate_cookie(cookies):
            # 失败重试
            if retry <= self.max_login_retry:
                retry = retry + 1
                logger.info('--> 登录失败重试: %s次' % retry)
                return self.__get_cookies(retry)
            else:
                logger.info('--> 放弃失败重试: %s次' % retry)
                return dict()

        logger.info('--> 登录成功: %s次' % retry)
        return cookies

    # cookie校验
    def _validate_cookie(self, cookies):
        for must_key in self.cookie_white_list:
            # 必要字段校验
            if not cookies or (must_key not in cookies) or (cookies.get(must_key) is None) or (cookies.get(must_key) is ''):
                logger.info('--> Cookie未通过校验: key=%s, cookie=%s' % (must_key, cookies))
                return False
        return True


if __name__ == '__main__':
    login = SeleniumLogin()
    cookie = login.get_cookies()
    print(cookie)
